<?php
class NGenericObject{
 private $id;
 private $table_name;
 private $database_fields;
 private $loaded;
 private $modified_fields;
/*
 public function &getInstance($table_name,$id=null){
	static $instances;
	if (!isset( $instances )) {
			$instances = array();
	}
	$key = $table_name.$id
	if (empty($instances[$table_name])){
	
	}
 }
 */
 public function &newInstance($table_name,$tuple_id=null){
	$oObject =  new NGenericObject;
	$oObject->Initialize($table_name, $tuple_id);
	return $oObject;
	
 }
 public function &NI($table_name,$tuple_id=null){
	return NGenericObject::newInstance($table_name,$tuple_id);
	
 }
 public function Reload(){
	$db = NFactory::getDBO();
	$id = $this->id;
	$table_name = $this->table_name;
	$db->setQuery("SELECT * FROM `$table_name` WHERE id='$id'",0,1);
	$result_fields = $db->loadAssoc();
	$this->database_fields=$result_fields;
	$this->loaded=1;
	if (sizeof($this->modified_fields)>0){	
		foreach($this->modified_fields as $key=>$value){
			$this->modified_fields[$key]=false;
		}
	}
	
 }
  public function Load(){
	$this->Reload();
	$this->loaded=1;
  }
  public function ForceLoaded(){
	$this->loaded=1;
  }
  public function GetField($field){
	if ($this->loaded == 0 && $this->id){
		$this->Load();
	};
	return $this->database_fields[$field];
  }
  public function GetAllFields(){
	if ($this->loaded == 0){
		$this->Load();
	};
	return ($this->database_fields);
  }
  public function GetID(){
	return $this->id;
  }
  public function Initialize($table_name, $tuple_id=""){
	$this->table_name = $table_name;
	$this->id = $tuple_id;
  }
  public function SetField($field,$value){
	if ($this->loaded == 0){
		if ($this->id) {
		 $this->Load();
		}
	}
	$this->database_fields[$field] = $value;
	$this->modified = 1;
	$this->modified_fields[$field] = true;
  }
  public function Destroy(){
	$id = $this->id;
	$table_name = $this->table_name;
	if ($id) {
		$db = NFactory::getDBO();
		$_sql ="DELETE FROM `".$table_name ."` WHERE id='" . $id ."'";
		//echo $_sql;
		$db->Execute( $_sql );
	}
  }
  public function Save(){
	$id = $this->id;
   	$table_name = $this->table_name;
	$db = NFactory::getDBO();
	if (!$id){
		$this->loaded = 0;
	}
	if ($this->loaded == 0){
	  #новая сущность
	  $_sql = "INSERT INTO `".$table_name."` (";
	  foreach ($this->database_fields as $key=>$value){
		if (!is_numeric($key)){
			$key = str_replace("'", "\'",$key);
			if ($value !=""){
				$_sql .= "`$key`,";
			}
		}
	  }
	
	  #удаление последней запятой
	  $_sql = substr($_sql,0,strlen($_sql)-1);
	  $_sql .= ") VALUES (";
	  foreach ($this->database_fields as $key=> $value){
		if (!is_numeric($key)){
			if ($value !=""){
				$value = str_replace("'","\'", $value);
				$_sql .= "'$value',";
			}
		}
	  }
	  #удаление последней запятой
	  $_sql = substr($_sql,0,strlen($_sql)-1);
	  $_sql .= ")";
	} else  {
	 	$_sql = "UPDATE `" .$table_name ."` SET ";
		foreach ($this->database_fields as $key => $value){
			if (!is_numeric($key)){
				if ($this->modified_fields[$key] == true){
					$value = str_replace("'","\'", $value);
					if ($value == "") {
						$_sql .= "`$key` = NULL, ";
					
					} else {
						$_sql .= "`$key` = '$value', ";
					}
				}
			}
		}
		# Удаление последней запятой и пробела
		$_sql = substr($_sql,0,strlen($_sql)-2);
		$_sql .= " WHERE id='$id'";
	}
	//echo $db->replacePrefix($_sql);
	$return_code =$db->Execute($_sql);
	if ($this->loaded ==0 ){
		#Попытка получения нового ID
		/** 
		* TODO get_insert_id
		*/
/*
		$_sql = "SELECT MAX(id) AS id FROM `$table_name` WHERE ";
		
		foreach ($this->database_fields as $key => $value){
			if (!is_numeric($key)){
				if ($value){
					if ($this->modified_fields[$key] == true){
						$value = str_replace("'","\'",$value);
						$_sql .= "`$key` = '$value' AND ";
					}
				}
			}
		}
		#Удаление последнего лишнего " AND "
		$_sql = substr($_sql, 0,strlen($_sql)-5);
		$db->setQuery($_sql,0,1);
		//echo $db->replacePrefix($_sql);
		$result_rows = $db->loadAssoc();
		//print_r($result_rows);


		$proposed_id = $result_rows['id'];
*/
		$proposed_id = $db->get_insert_id();
		
		if ($proposed_id > 0) {
			$this->loaded = 1;
			$this->id = $proposed_id;
			return true;
		} else {
			return false;
		}
	}
	return ($return_code);
  }
}

?>